package com.common.utils
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.TimerEvent;
	import flash.utils.Dictionary;
	import flash.utils.Timer;
	import flash.utils.getTimer;

	public class SharedEnterFrame
	{
		private static var _instance:SharedEnterFrame;
		private static var targetToFunction:Dictionary;

		/**
		 * 單態池引用
		 */
		public static function get instance():SharedEnterFrame
		{

			if (!_instance)
				_instance=new SharedEnterFrame();
			return _instance;
		}

		public function destroy():void
		{
			targetToFunction=null;
			timers=null;
			timerToFuns=null;
			funToFps=null;

			_instance=null;
		}

		private var timers:Dictionary;
		private var timerToFuns:Dictionary;
		private var funToFps:Dictionary;

		//---------------------------------------------------------
		// 構造函數
		//---------------------------------------------------------
		public function SharedEnterFrame()
		{
			timers=new Dictionary();
			timerToFuns=new Dictionary();
			funToFps=new Dictionary();
		}

		private function onTimer(event:TimerEvent):void
		{
			var timer:Timer=event.target as Timer;
			if (timerToFuns == null)
				return;
			var funs:Dictionary=timerToFuns[timer];

			for (var fun:* in funs)
			{
				if (fun != null)
					fun();
			}

		}

		public function addFrameCall(fun:Function, frameRate:Number):void
		{
			if (fun != null && funToFps[fun] === undefined)
			{
				var timer:Timer=timers[frameRate]||=new Timer(int(1000 / frameRate));
				var funs:Dictionary=timerToFuns[timer]||=new Dictionary();
				funs[fun]=null;
				funToFps[fun]=frameRate;
				timer.addEventListener(TimerEvent.TIMER, onTimer);
				!timer.running && timer.start();
			}
		}

		public function removeFrameCall(fun:Function):void
		{
			if (fun != null && !(funToFps[fun] === undefined))
			{
				var fps:int=funToFps[fun];
				var timer:Timer=timers[fps];
				var funs:Dictionary=timerToFuns[timer];
				delete funs[fun];
				delete funToFps[fun];

				var hasFunsForTimer:Boolean=false;
				for (var key:* in funs)
				{
					hasFunsForTimer=true;
					break;
				}
				if (!hasFunsForTimer)
				{
					timer.stop();
					delete timers[fps];
				}
			}
		}
	}
}
